home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 52 / Amiga Format AFCD52 (Issue 136, May 2000).iso / -serious- / programming / other / systracker_src / src / st_patches_asm.s < prev    next >
Encoding:
Text File  |  2000-02-28  |  28.8 KB  |  939 lines

  1.  
  2. ;***************************************************************************;
  3. ;
  4. ; SysTracker version 0.x assembly patch support routines.
  5. ;
  6. ; Created: Thu/4/Nov/1999
  7. ;
  8. ; Copyright © 1999 Andrew Bell. All rights reserved.
  9. ;
  10. ;***************************************************************************;
  11.  
  12.                 ; Because of the random and really annoying lock up
  13.                 ; bugs between Hisoft C++ and MaxonASM, This source is
  14.                 ; compiled with the excellent PhxAss assembler v4.xx by
  15.                 ; Frank Wille. This time the free software wins over the
  16.                 ; expensive commercial bugware. :-/
  17.  
  18.                 MC68020
  19.  
  20.                 IFD     _PHXASS_
  21.                 OPT     3
  22.                 TTL     st_patches
  23.                 ENDC
  24.  
  25. ;***************************************************************************;
  26. ; System Includes ;
  27.  
  28.                 incdir  mdev:amiga/asm-inc
  29.                 include exec/macros.i
  30.                 include exec/ports.i
  31.                 include exec/nodes.i
  32.                 include exec/memory.i
  33.                 include dos/dosextens.i
  34.                 include utility/tagitem.i
  35.                 include graphics/text.i
  36.  
  37. ;***************************************************************************;
  38. ; Defines and external references ;
  39.  
  40. FALSE           =       0
  41. TRUE            =       1
  42.  
  43. PATCHREGS       reg     d1-d7/a0-a6     ; Keep all but D0.
  44. PATCHREGS_ALL   reg     d0-d7/a0-a6     ; Keep all.
  45.  
  46.                         rsset   0               ; PatchMsg
  47. pmsg_MsgHeader          rs.b    MN_SIZE
  48. pmsg_ID                 rs.l    1
  49. pmsg_TaskPtr            rs.l    1
  50. pmsg_TaskName           rs.l    1
  51. pmsg_TaskType           rs.l    1
  52. pmsg_TaskFrozen         rs.w    1
  53. pmsg_Padding01          rs.w    1
  54. pmsg_CmdName            rs.l    1
  55. pmsg_LaunchType         rs.l    1
  56. pmsg_SegList            rs.l    1
  57. pmsg_LibType            rs.l    1
  58. pmsg_LibName            rs.l    1
  59. pmsg_LibVer             rs.l    1
  60. pmsg_LibBase            rs.l    1
  61. pmsg_DevName            rs.l    1
  62. pmsg_DevUnitNum         rs.l    1
  63. pmsg_DevIOReq           rs.l    1
  64. pmsg_DevFlags           rs.l    1
  65. pmsg_FontTextAttr       rs.l    1
  66. pmsg_FontTextFont       rs.l    1
  67. pmsg_FontName           rs.l    1
  68. pmsg_FontYSize          rs.w    1
  69. pmsg_FontStyle          rs.b    1
  70. pmsg_FontFlags          rs.b    1
  71. pmsg_FHName             rs.l    1       ; UBYTE *
  72. pmsg_FHMode             rs.l    1       ; Signed LONG
  73. pmsg_FH                 rs.l    1       ; BPTR
  74. pmsg_LockName           rs.l    1       ; UBYTE *
  75. pmsg_LockMode           rs.l    1       ; Signed LONG
  76. pmsg_Lock               rs.l    1       ; BPTR
  77. pmsg_CurDirName         rs.l    1       ; UBYTE *
  78. pmsg_SIZEOF             rs.l    0
  79.  
  80. LT_NA                   = 0        ; For pmsg_LaunchType
  81. LT_CLI                  = 1
  82. LT_WB                   = 2
  83.  
  84. PMSGID_ALL              = -1
  85. PMSGID_UNKNOWN          =  0
  86. PMSGID_OPENLIBRARY      =  1
  87. PMSGID_OPENDEVICE       =  2
  88. PMSGID_CLOSELIBRARY     =  3
  89. PMSGID_CLOSEDEVICE      =  4
  90. PMSGID_OPENFONT         =  5
  91. PMSGID_CLOSEFONT        =  6
  92. ;PMSGID_OPENDISKFONT    =  7 ; *** Obsolete ***
  93. ;PMSGID_MAKELIBRARY     =  8 ; *** Obsolete ***
  94. PMSGID_OPEN             =  9
  95. PMSGID_CLOSE            =  10
  96. PMSGID_LOCK             =  11
  97. PMSGID_UNLOCK           =  12
  98. PMSGID_OPENFROMLOCK     =  13
  99.  
  100. BUFLEN                  = 256
  101.  
  102.                 xref    _LVOPutMsg
  103.                 xref    _LVOFindTask
  104.                 xref    _LVOOpenLibrary
  105.                 xref    _LVOCloseLibrary
  106.                 xref    _LVOObtainSemaphore
  107.                 xref    _LVOReleaseSemaphore
  108.                 xref    _LVOAllocPooled
  109.                 xref    _LVOFreePooled
  110.                 xref    _LVOLock
  111.                 xref    _LVOUnLock
  112.                 xref    _LVOOpenFont
  113.                 xref    _LVOCloseFont
  114.                 xref    _LVONameFromLock
  115.                 xref    _LVOGetCurrentDirName
  116.                 xref    _LVOIoErr
  117.                 xref    _LVOSetIoErr
  118.  
  119. ;***************************************************************************;
  120. ; Assorted macros ;
  121.  
  122. PUSH            MACRO
  123.                 movem.l \1,-(sp)
  124.                 ENDM
  125.  
  126. PULL            MACRO
  127.                 movem.l (sp)+,\1
  128.                 ENDM
  129.  
  130. CALLOS          MACRO
  131.                 jsr     _LVO\1(a6)
  132.                 ;move.l #$a000dead,a0   ; This is temporary.
  133.                 ;move.l #$a100dead,a1
  134.                 ENDM
  135.  
  136. PATCHID         MACRO
  137.                 ;
  138.                 ; This is a small sig that allows virus checkers and the
  139.                 ; like to quickly identify our patches.
  140.                 ;
  141.                 bra.b   \@_SkipID
  142.                 dc.b    "«« SysTracker-Patch »»"
  143.                 cnop    0,4
  144. \@_SkipID       
  145.                 ENDM
  146.  
  147. NEWPMSG         MACRO   ; \1 = ID, \2 = Exit label
  148.                 ;
  149.                 bsr     _PATCH_CreatePatchMsg
  150.                 beq.b   \2
  151.                 move.l  d0,a2
  152.                 move.l  \1,d0
  153.                 move.l  d0,pmsg_ID(a2)
  154.                 ;
  155.                 ENDM
  156.  
  157. ;***************************************************************************;
  158. ; Notes ;
  159. ;
  160. ; - Most of the code below is called on the context of alien tasks, this
  161. ;   means all of the code MUST be thread safe, if this is not possible
  162. ;   semaphores need to be used.
  163. ;
  164. ; - Always make sure the IoErr() code is kept intact if calling functions
  165. ;   that modify it. Programs like Multiview and CED v4 tend to get very
  166. ;   upset when their IoErr() code is modified by a patch. In fact, it took
  167. ;   me many hours to track down a bug that was caused by this.
  168. ;
  169. ; - Stack usage *really* needs to be reduced. ATM, the patches push all
  170. ;   registers onto the stack, regardless of whether they're being used or
  171. ;   not.
  172. ;
  173. ; - Some of these routines could easily be upcoded to C, but this would
  174. ;   probably impact on SysTracker's performance, in a big way.
  175. ;
  176.  
  177. ;**************************************************************************;
  178. ; Patch for exec.library/OpenLibrary() ;
  179.  
  180.                 xdef    _PATCH_NewOpenLibrary
  181.                 xref    _OriginalOpenLibrary
  182.  
  183. _PATCH_NewOpenLibrary           ; d0=LibVersion, a1=LibName, a6=SysBase
  184.                 PATCHID
  185.                 PUSH    PATCHREGS
  186.  
  187.                 move.l  a1,d6           ; d6=library name
  188.                 move.l  d0,d7           ; d7=version
  189. .CallReal       move.l  _OriginalOpenLibrary,a3
  190.                 jsr     (a3)
  191.                 move.l  d0,d5           ; d5=Base
  192.  
  193.                 move.l  d6,d0           ; No library name?
  194.                 beq.b   .Exit
  195.  
  196.                 NEWPMSG #PMSGID_OPENLIBRARY,.Exit
  197.                 move.l  d7,pmsg_LibVer(a2)
  198.                 move.l  d5,pmsg_LibBase(a2)
  199.                 move.l  d6,a0
  200.                 bsr     _PATCH_StrToVec
  201.                 move.l  d0,pmsg_LibName(a2)
  202.                 beq.b   .FailFreePM
  203.                 bsr     _PATCH_DispatchPatchMsg
  204.                 bra.b   .Exit
  205. .FailFreePM     move.l  a2,a0
  206.                 bsr     _PATCH_DeletePatchMsg
  207.  
  208. .Exit           move.l  d5,d0
  209.                 PULL    PATCHREGS
  210.                 rts
  211.  
  212. ;***************************************************************************;
  213. ; Patch for exec.library/CloseLibrary() ;
  214.  
  215.                 xdef    _PATCH_NewCloseLibrary
  216.                 xref    _OriginalCloseLibrary
  217.  
  218. _PATCH_NewCloseLibrary                  ; a1=LibBase, a6=SysBase
  219.                 PATCHID
  220.                 PUSH    PATCHREGS_ALL
  221.  
  222.                 move.l  a1,d2           ; d2=LibBase
  223.                 beq.b   .Exit
  224.                 move.l  LN_NAME(a1),a0
  225.                 bsr     _PATCH_StrToVec
  226.                 move.l  d0,d3           ; d3=LibNameVec
  227.  
  228.                 move.l  _OriginalCloseLibrary,a3
  229.                 jsr     (a3)
  230.                 tst.l   d3
  231.                 beq.b   .Exit
  232.  
  233.                 NEWPMSG #PMSGID_CLOSELIBRARY,.Exit
  234.                 move.l  d2,pmsg_LibBase(a2)
  235.                 move.l  d3,pmsg_LibName(a2)
  236.                 bsr     _PATCH_DispatchPatchMsg
  237.  
  238. .Exit           PULL    PATCHREGS_ALL
  239.                 rts
  240.  
  241. ;***************************************************************************;
  242. ; Patch for exec.library/OpenDevice() ;
  243.  
  244.                 xdef    _PATCH_NewOpenDevice
  245.                 xref    _OriginalOpenDevice
  246.  
  247. _PATCH_NewOpenDevice ; a0=DevName, d0=UnitNum, a1=IOReq, d1=Flags, a6=SysBase
  248.                 PATCHID
  249.                 PUSH    PATCHREGS
  250.  
  251.                 move.l  _OriginalOpenDevice,a3
  252.                 PUSH    a0-a1/d0-d1
  253.                 jsr     (a3)
  254.                 PULL    a0-a1/d1-d2
  255.                 move.l  d0,d3
  256.                 bne.b   .Exit           ; Note: 0 for success
  257.  
  258.                 move.l  a0,d4
  259.                 beq.b   .Exit
  260.  
  261.                 NEWPMSG #PMSGID_OPENDEVICE,.Exit
  262.                 bsr     _PATCH_StrToVec
  263.                 move.l  d0,pmsg_DevName(a2)
  264.                 beq.b   .FailFreePM             
  265.                 move.l  a1,pmsg_DevIOReq(a2)
  266.                 move.l  d1,pmsg_DevUnitNum(a2)
  267.                 move.l  d2,pmsg_DevFlags(a2)
  268.                 bsr     _PATCH_DispatchPatchMsg
  269.                 bra.b   .Exit
  270. .FailFreePM     move.l  a2,a0
  271.                 bsr     _PATCH_DeletePatchMsg
  272.  
  273. .Exit           move.l  d3,d0
  274.                 PULL    PATCHREGS
  275.                 rts
  276.  
  277. ;***************************************************************************;
  278. ; Patch for exec.library/CloseDevice() ;
  279.  
  280.                 xdef    _PATCH_NewCloseDevice
  281.                 xref    _OriginalCloseDevice
  282.  
  283. _PATCH_NewCloseDevice           ; a1=IOReq, a6=SysBase
  284.                 PATCHID
  285.                 PUSH    PATCHREGS_ALL
  286.  
  287.                 move.l  a1,a4
  288.                 move.l  _OriginalCloseDevice,a3
  289.                 jsr     (a3)
  290.                 move.l  a4,d0
  291.                 beq.b   .Exit
  292.  
  293.                 NEWPMSG #PMSGID_CLOSEDEVICE,.Exit
  294.                 move.l  a4,pmsg_DevIOReq(a2)
  295.                 bsr     _PATCH_DispatchPatchMsg
  296.  
  297. .Exit           PULL    PATCHREGS_ALL
  298.                 rts
  299.  
  300. ;***************************************************************************;
  301. ; Patch for graphics.library/OpenFont() + diskfont.library/OpenDiskFont() ;
  302.  
  303.                 xdef    _PATCH_NewOpenFont
  304.                 xref    _OriginalOpenFont
  305.                 xref    _OriginalOpenDiskFont
  306.                 xref    _SysBase
  307.  
  308.                 REM
  309.  
  310.                 xdef    _PATCH_NewOpenDiskFont
  311.  
  312. _PATCH_NewOpenDiskFont                  ; a0=TextAttr
  313.                 PATCHID
  314.                 PUSH    PATCHREGS
  315.                 moveq   #PMSGID_OPENDISKFONT,d4
  316.                 move.l  _OriginalOpenDiskFont,a3
  317.                 bra.b   _PATCH_OpenFontEntry
  318.  
  319.                 EREM
  320.  
  321. _PATCH_NewOpenFont                      ; a0=TextAttr
  322.                 PATCHID
  323.                 PUSH    PATCHREGS
  324.                 moveq   #PMSGID_OPENFONT,d4
  325.                 move.l  _OriginalOpenFont,a3
  326.  
  327. _PATCH_OpenFontEntry
  328.                 move.l  a0,a4
  329.                 jsr     (a3)
  330.                 move.l  d0,d3
  331.                 move.l  a4,d0
  332.                 beq.b   .Exit
  333.  
  334.                 NEWPMSG d4,.Exit
  335.                 move.l  a4,pmsg_FontTextAttr(a2)
  336.                 move.l  d3,pmsg_FontTextFont(a2)        ; Note: May be NULL
  337.                 move.w  ta_YSize(a4),pmsg_FontYSize(a2)
  338.                 move.b  ta_Style(a4),pmsg_FontStyle(a2)
  339.                 move.b  ta_Flags(a4),pmsg_FontFlags(a2)
  340.                 move.l  ta_Name(a4),a0
  341.                 move.l  a0,d0
  342.                 bne.b   .FontNameOK
  343.                 lea.l   STR_UnnamedFont(pc),a0
  344. .FontNameOK     bsr     _PATCH_StrToVec
  345.                 move.l  d0,pmsg_FontName(a2)
  346.                 beq.b   .FailFreePM
  347.                 bsr     _PATCH_DispatchPatchMsg
  348.                 bra.b   .Exit
  349. .FailFreePM     move.l  a2,a0
  350.                 bsr     _PATCH_DeletePatchMsg
  351.  
  352. .Exit           move.l  d3,d0
  353.                 PULL    PATCHREGS
  354.                 rts
  355.  
  356. ;***************************************************************************;
  357. ; Patch for graphics.library/CloseFont() ;
  358.  
  359.                 xdef    _PATCH_NewCloseFont
  360.                 xref    _OriginalCloseFont
  361.  
  362. _PATCH_NewCloseFont             ; a1=TextFont
  363.                 PATCHID
  364.                 PUSH    PATCHREGS_ALL
  365.  
  366.                 move.l  a1,a4
  367.                 move.l  _OriginalCloseFont,a3
  368.                 jsr     (a3)
  369.                 move.l  a4,d0
  370.                 beq.b   .Exit
  371.  
  372.                 NEWPMSG #PMSGID_CLOSEFONT,.Exit
  373.                 move.l  a4,pmsg_FontTextFont(a2)
  374.                 bsr     _PATCH_DispatchPatchMsg
  375.  
  376. .Exit           PULL    PATCHREGS_ALL
  377.                 rts
  378.  
  379. ;***************************************************************************;
  380. ; Patch for dos.library/Open() ;
  381.  
  382.                 xdef    _PATCH_NewOpen
  383.                 xref    _OriginalOpen
  384.  
  385. _PATCH_NewOpen
  386.                 PATCHID                 ; d1=Name, d2=AccessMode
  387.                 PUSH    PATCHREGS
  388.  
  389.                 move.l  d1,d6
  390.                 move.l  d2,d7
  391.  
  392.                 move.l  _OriginalOpen,a3
  393.                 jsr     (a3)
  394.                 move.l  d0,d5           ; d5=filehandle
  395.  
  396.                 move.l  d6,d0           ; No file name?
  397.                 beq.b   .Exit
  398.  
  399.                 NEWPMSG #PMSGID_OPEN,.Exit
  400.                 move.l  d7,pmsg_FHMode(a2)
  401.                 move.l  d5,pmsg_FH(a2)
  402.                 move.l  d6,a0
  403.                 bsr     _PATCH_StrToVec
  404.                 move.l  d0,pmsg_FHName(a2)
  405.                 beq.b   .FailFreePM
  406.                 bsr     _PATCH_StoreCDName
  407.                 bsr     _PATCH_DispatchPatchMsg
  408.                 bra.b   .Exit
  409. .FailFreePM     move.l  a2,a0
  410.                 bsr     _PATCH_DeletePatchMsg
  411.  
  412. .Exit           move.l  d5,d0
  413.                 PULL    PATCHREGS
  414.                 rts
  415.  
  416. ;***************************************************************************;
  417. ; Patch for dos.library/Close() ;
  418.  
  419.                 xdef    _PATCH_NewClose
  420.                 xref    _OriginalClose
  421.  
  422. _PATCH_NewClose PATCHID                 ; d1=FileHandle
  423.                 PUSH    PATCHREGS_ALL
  424.  
  425.                 move.l  d1,d2
  426.                 move.l  _OriginalClose,a3
  427.                 jsr     (a3)
  428.                 tst.l   d2
  429.                 beq.b   .Exit
  430.  
  431.                 NEWPMSG #PMSGID_CLOSE,.Exit
  432.                 move.l  d2,pmsg_FH(a2)
  433.                 bsr     _PATCH_DispatchPatchMsg
  434.  
  435. .Exit           PULL    PATCHREGS_ALL
  436.                 rts
  437.  
  438.  
  439. ;***************************************************************************;
  440. ; Patch for dos.library/Lock() ;
  441.  
  442.                 xdef    _PATCH_NewLock
  443.                 xref    _OriginalLock
  444.  
  445. _PATCH_NewLock  PATCHID
  446.                 PUSH    d2-d7/a0-a6     ; d1=Name, d2=AccessMode
  447.  
  448.                 move.l  d1,d6
  449.                 move.l  d2,d7
  450.  
  451.                 move.l  _OriginalLock,a3
  452.                 jsr     (a3)
  453.                 move.l  d1,-(sp)
  454.                 move.l  d0,d5           ; d5=Lock
  455.  
  456.                 move.l  d6,d0           ; No file name?
  457.                 beq.b   .Exit
  458.  
  459.                 NEWPMSG #PMSGID_LOCK,.Exit
  460.                 move.l  d7,pmsg_LockMode(a2)
  461.                 move.l  d5,pmsg_Lock(a2)
  462.                 move.l  d6,a0
  463.                 bsr     _PATCH_StrToVec
  464.                 move.l  d0,pmsg_LockName(a2)
  465.                 beq.b   .FailFreePM
  466.                 bsr     _PATCH_StoreCDName
  467.                 bsr     _PATCH_DispatchPatchMsg
  468.                 bra.b   .Exit
  469. .FailFreePM     move.l  a2,a0
  470.                 bsr     _PATCH_DeletePatchMsg
  471.  
  472. .Exit           move.l  (sp)+,d1        ; Just in case ;)
  473.                 move.l  d5,d0
  474.                 PULL    d2-d7/a0-a6
  475.                 rts
  476.  
  477. ;***************************************************************************;
  478. ; Patch for dos.library/UnLock() ;
  479.  
  480.                 xdef    _PATCH_NewUnLock
  481.                 xref    _OriginalUnLock
  482.  
  483. _PATCH_NewUnLock
  484.                 PATCHID                 ; d1=Lock
  485.                 PUSH    PATCHREGS_ALL
  486.  
  487.                 move.l  d1,d2
  488.                 move.l  _OriginalUnLock,a3
  489.                 jsr     (a3)
  490.  
  491.                 NEWPMSG #PMSGID_UNLOCK,.Exit
  492.                 move.l  d2,pmsg_Lock(a2)
  493.                 bsr     _PATCH_DispatchPatchMsg
  494.  
  495. .Exit           PULL    PATCHREGS_ALL
  496.                 rts
  497.  
  498. ;***************************************************************************;
  499. ; Patch for dos.library/OpenFromLock() ;
  500.  
  501.                 xdef    _PATCH_NewOpenFromLock
  502.                 xref    _OriginalOpenFromLock
  503.  
  504.         ; [Note: if original call succeeds, then the lock is no more]
  505.  
  506. _PATCH_NewOpenFromLock
  507.                 PATCHID         ; d1=lock 
  508.                 PUSH    PATCHREGS
  509.  
  510.                 bsr     _PATCH_LockNameToVec
  511.                 move.l  d0,d2
  512.  
  513.                 move.l  d1,d3
  514.                 move.l  _OriginalOpenFromLock,a3
  515.                 jsr     (a3)
  516.                 move.l  d0,d5                   ; d5=FileHandle
  517.  
  518.                 tst.l   d2              ; ...LockNameToVec() failed?
  519.                 beq.b   .Exit
  520.  
  521.                 NEWPMSG #PMSGID_OPENFROMLOCK,.Exit
  522.                 move.l  d3,pmsg_Lock(a2)
  523.                 move.l  d5,pmsg_FH(a2)
  524.                 move.l  d2,pmsg_FHName(a2)
  525.  
  526.                 bsr     _PATCH_DispatchPatchMsg
  527.  
  528. .Exit           move.l  d5,d0
  529.                 PULL    PATCHREGS
  530.                 rts
  531.  
  532. ;***************************************************************************;
  533. ; PATCH_CreatePatchMsg() ; Allocate and initialize a patch message. ;
  534. ;
  535. ; Will also setup some defaults too and collect information on the
  536. ; calling task.
  537. ;
  538. ; void PATCH_CreatePatchMsg();
  539.  
  540.                 xref    _SysTrackerProcess
  541.                 xref    _ARTLProcess
  542.  
  543. _PATCH_CreatePatchMsg
  544.                 PUSH    d1-a6
  545.  
  546.                 move.l  _SysBase,a6
  547.  
  548.                 suba.l  a1,a1
  549.                 CALLOS  FindTask
  550.                 tst.l   d0
  551.                 beq     .Exit                   ; Just in case ;)
  552.                 move.l  d0,a4                   ; a4=ThisTask
  553.  
  554.                 moveq   #0,d0                   ; Don't send msgs on the 
  555.                 move.l  _SysTrackerProcess,d1   ; context of our own task.
  556.                 cmp.l   a4,d1
  557.                 beq.b   .Exit
  558.                 move.l  _ARTLProcess,d1         ; Nor the ARTLProcess'
  559.                 cmp.l   a4,d1
  560.                 beq.b   .Exit
  561.  
  562.                 move.l  #pmsg_SIZEOF,d0
  563.                 bsr     _PATCH_AllocVec
  564.                 beq.b   .Exit
  565.                 move.l  d0,a2
  566.  
  567.                 move.l  a4,pmsg_TaskPtr(a2)     ; Setup the basics
  568.                 move.w  #pmsg_SIZEOF,MN_LENGTH(a2)
  569.                 move.b  #NT_MESSAGE,LN_TYPE(a2)
  570.  
  571.                 moveq   #0,d1
  572.                 move.b  LN_TYPE(a4),d1
  573.                 move.l  d1,pmsg_TaskType(a2)
  574.                 move.l  LN_NAME(a4),a0
  575.                 bsr     _PATCH_StrToVec
  576.                 move.l  d0,pmsg_TaskName(a2)
  577.                 beq.b   .Fail
  578.  
  579.                 moveq   #LT_NA,d2               ; Let's assume we're just an
  580.                 move.l  d2,pmsg_LaunchType(a2)  ;  ordinary exec task.
  581.  
  582.                 cmp.b   #NT_PROCESS,d1          ; Must be a process to
  583.                 bne.b   .SetResAndExit          ;  proceed with the next part.
  584.                 moveq   #LT_WB,d2               ; OK, so we're not a task,
  585.                 move.l  d2,pmsg_LaunchType(a2)  ;  but we're a process, so
  586.                                                 ;  lets assume we're from WB.
  587.                 move.l  pr_CLI(a4),d0
  588.                 beq.b   .SetResAndExit
  589.                 moveq   #LT_CLI,d2              ; OK, at this point, we know
  590.                 move.l  d2,pmsg_LaunchType(a2)  ;  we're from CLI, not WB.
  591.  
  592.                 lsl.l   #2,d0
  593.                 move.l  d0,a0
  594.                 move.l  cli_Module(a0),pmsg_SegList(a2)
  595.                 move.l  cli_CommandName(a0),d0  ; Get the command name
  596.                 beq.b   .SetResAndExit
  597.                 bsr     _PATCH_BSTRToVec
  598.                 move.l  d0,pmsg_CmdName(a2)     ; It's OK if this fails.
  599.  
  600. .SetResAndExit  move.l  a2,d0
  601.                 bra.b   .Exit
  602.  
  603. .Fail           move.l  a2,a0
  604.                 bsr.b   _PATCH_DeletePatchMsg
  605.                 moveq   #0,d0
  606.  
  607. .Exit           PULL    d1-a6
  608.                 tst.l   d0
  609.                 rts
  610.  
  611. ;***************************************************************************;
  612. ; PATCH_StoreCDName() ; Store the current dir name in a PMsg;
  613. ;
  614. ; void PATCH_StoreCDName( register __a2 struct PatchMsg *PMsg );
  615.  
  616.                 xdef    _PATCH_StoreCDName
  617.  
  618. _PATCH_StoreCDName:
  619.                 PUSH    d1-d3/d7/a0-a1/a6
  620.  
  621.                 move.l  _DOSBase,a6
  622.  
  623.                 CALLOS  IoErr   ; Note: We *MUST* keep the existing IoErr
  624.                 move.l  d0,d7   ;       code intact!
  625.  
  626.                 move.l  #256,d2
  627.                 move.l  d2,d0
  628.                 bsr     _PATCH_AllocVec
  629.                 move.l  d0,d3
  630.                 beq.b   .Exit
  631.                 move.l  d0,d1
  632.  
  633.                 CALLOS  GetCurrentDirName
  634.                 tst.l   d0
  635.                 bne.b   .Exit   ; OK
  636.  
  637.                 move.l  d3,a1
  638.                 bsr     _PATCH_FreeVec
  639.                 moveq   #0,d3
  640.  
  641. .Exit           move.l  d7,d1
  642.                 CALLOS  SetIoErr
  643.  
  644.                 move.l  d3,pmsg_CurDirName(a2)
  645.                 move.l  d3,d0
  646.                 PULL    d1-d3/d7/a0-a1/a6
  647.                 tst.l   d0
  648.                 rts
  649.  
  650. ;***************************************************************************;
  651. ; PATCH_DeletePatchMsg() ; Free a patch message ;
  652. ;
  653. ; void PATCH_DeletePatchMsg( register __a0 struct PatchMsg *PMsg );
  654.  
  655.                 xdef    _PATCH_DeletePatchMsg
  656.                 xdef    @PATCH_DeletePatchMsg   ; DICE needs this
  657.  
  658. @PATCH_DeletePatchMsg
  659. _PATCH_DeletePatchMsg
  660.                 PUSH    a0-a2/d0-d1
  661.  
  662.                 move.l  a0,d0
  663.                 beq.b   .Exit
  664.  
  665.                 moveq   #-1,d1
  666.                 move.l  d1,-(sp)
  667.                 move.l  a0,-(sp)
  668.  
  669.                 move.l  pmsg_CurDirName(a0),-(sp)
  670.                 move.l  pmsg_LockName(a0),-(sp)
  671.                 move.l  pmsg_FHName(a0),-(sp)
  672.                 move.l  pmsg_TaskName(a0),-(sp)
  673.                 move.l  pmsg_LibName(a0),-(sp)
  674.                 move.l  pmsg_CmdName(a0),-(sp)
  675.                 move.l  pmsg_DevName(a0),-(sp)
  676.                 move.l  pmsg_FontName(a0),-(sp)
  677.                 lea.l   _PATCH_FreeVec(pc),a2
  678.  
  679. .Lp             move.l  (sp)+,d0
  680.                 beq.b   .Lp
  681.                 cmp.l   d1,d0
  682.                 beq.b   .Exit
  683.                 move.l  d0,a1
  684.                 jsr     (a2)
  685.                 bra.b   .Lp
  686.  
  687. .Exit           PULL    a0-a2/d0-d1
  688.                 rts
  689.  
  690. ;***************************************************************************;
  691. ; _PATCH_DispatchPatchMsg() ; Dispatch a Patch message ;
  692. ;
  693. ; void PATCH_DispatchPatchMsg( register __a2 struct PatchMsg *PMsg );
  694.  
  695.                 xdef    _PATCH_DispatchPatchMsg
  696.                 xref    _PatchPort
  697.  
  698. _PATCH_DispatchPatchMsg
  699.                 PUSH    d0-d1/a0-a1/a6
  700.  
  701.                 move.l  _SysBase,a6
  702.  
  703.                 move.l  _PatchPort,d0
  704.                 beq.b   .Exit
  705.                 move.l  d0,a0           ; Dispatch the information
  706.                 move.l  a2,a1
  707.                 CALLOS  PutMsg
  708.  
  709. .Exit           PULL    d0-d1/a0-a1/a6
  710.                 rts
  711.  
  712. ;***************************************************************************;
  713. ; PATCH_StrToVec() ; Copy a string to a vector ;
  714. ;
  715. ; UBYTE *PATCH_StrToVec( register __a0 UBYTE *Str );
  716.  
  717.                 xdef    _PATCH_StrToVec
  718.  
  719. _PATCH_StrToVec PUSH    a0-a2/d1
  720.  
  721.                 move.l  a0,d0
  722.                 beq.b   .Fail
  723.  
  724.                 move.l  a0,a2
  725.                 moveq   #-1,d0
  726. .StrLenLp       tst.b   (a0)+
  727.                 dbeq    d0,.StrLenLp
  728.                 not.l   d0
  729.                 addq.l  #1,d0
  730.                 bsr     _PATCH_AllocVec
  731.                 beq.b   .Fail
  732.  
  733.                 move.l  d0,a0
  734. .CopyStrLp      move.b  (a2)+,(a0)+
  735.                 bne.b   .CopyStrLp
  736.  
  737. .Fail           PULL    a0-a2/d1
  738.                 tst.l   d0
  739.                 rts
  740.  
  741. ;***************************************************************************;
  742. ; PATCH_StrCatVec ; Join two string and save in a vector ;
  743. ;
  744. ; UBYTE *PATCH_StrToVec( register __a0 UBYTE *Str1,
  745. ;                        register __a1 UBYTE *Str2 );
  746.  
  747.                 xdef    _PATCH_StrCatVec
  748.  
  749. _PATCH_StrCatVec
  750.                 PUSH    d1/a0-a3
  751.  
  752.                 move.l  a0,a2
  753.                 move.l  a1,a3
  754.                 moveq   #-1,d0
  755. .StrLenLp1      tst.b   (a0)+
  756.                 dbeq    d0,.StrLenLp1
  757.                 not.l   d0
  758.                 moveq   #-1,d1
  759. .StrLenLp2      tst.b   (a1)+
  760.                 dbeq    d1,.StrLenLp2
  761.                 not.l   d1
  762.                 add.l   d1,d0
  763.                 addq.l  #1,d0           ; Room for NULL termination
  764.                 bsr     _PATCH_AllocVec
  765.                 beq.b   .Exit
  766.  
  767.                 move.l  d0,a0
  768. .CopyLp1        move.b  (a2)+,(a0)+
  769.                 bne.b   .CopyLp1
  770.                 subq.l  #1,a0
  771. .CopyLp2        move.b  (a3)+,(a0)+
  772.                 bne.b   .CopyLp2
  773.  
  774. .Exit           PULL    d1/a0-a3
  775.                 tst.l   d0
  776.                 rts
  777.  
  778. ;***************************************************************************;
  779. ; PATCH_BSTRToVec() ; Copy a BSTR to a vector ;
  780. ;
  781. ; UBYTE *PATCH_BSTRToVec( register __d0 BSTR Str );
  782.  
  783.                 xdef    _PATCH_BSTRToVec
  784.  
  785. _PATCH_BSTRToVec
  786.                 PUSH    a0-a2/d1-d2
  787.  
  788.                 tst.l   d0
  789.                 beq.b   .Fail
  790.  
  791.                 lsl.l   #2,d0
  792.                 move.l  d0,a2
  793.                 moveq   #0,d2
  794.                 move.b  (a2)+,d2
  795.                 moveq   #4,d0           ; NULL + safety
  796.                 add.l   d2,d0
  797.                 bsr     _PATCH_AllocVec
  798.                 beq.b   .Fail
  799.  
  800.                 move.l  d0,a0
  801.                 bra.b   .IntoCopyLp
  802. .CopyLp         move.b  (a2)+,(a0)+
  803. .IntoCopyLp     dbf.w   d2,.CopyLp
  804.                 clr.b   (a0)
  805.  
  806. .Fail           PULL    a0-a2/d1-d2
  807.                 tst.l   d0
  808.                 rts
  809.  
  810. ;***************************************************************************;
  811. ; PATCH_AllocVec() ; Thread-safe pool allocation ;
  812. ;
  813. ; APTR PATCH_AllocVec( register __d0 ULONG ByteSize );
  814.  
  815.                 xdef    _PATCH_AllocVec
  816.                 xref    _PatchPool
  817.                 xref    _PatchPoolKey
  818.  
  819. _PATCH_AllocVec PUSH    a0-a3/a6/d1-d3
  820.  
  821.                 move.l  d0,d2           ; d2=ByteSize
  822.                 beq.b   .Exit
  823.                 move.l  _PatchPool,d0
  824.                 beq.b   .Exit
  825.                 move.l  d0,a2           ; a2=PatchPool
  826.  
  827.                 move.l  _SysBase,a6
  828.  
  829.                 lea.l   _PatchPoolKey,a0
  830.                 move.l  a0,a3           ; a3=PatchPoolKey
  831.                 CALLOS  ObtainSemaphore
  832.  
  833.                 addq.l  #4,d2
  834.                 move.l  a2,a0
  835.                 move.l  d2,d0
  836.                 CALLOS  AllocPooled
  837.                 move.l  d0,d3
  838.                 beq.b   .NoMem
  839.  
  840.                 move.l  d0,a0
  841.                 move.l  d2,(a0)+
  842.                 move.l  a0,d3
  843.  
  844. .NoMem          move.l  a3,a0
  845.                 CALLOS  ReleaseSemaphore
  846.  
  847.                 move.l  d3,d0
  848. .Exit           PULL    a0-a3/a6/d1-d3
  849.                 tst.l   d0
  850.                 rts
  851.  
  852. ;***************************************************************************;
  853. ; PATCH_FreeVec() ; Free the memory obtained by PATCH_AllocVec() ;
  854. ;
  855. ; void PATCH_FreeVec( register __a1 APTR Vec );
  856.  
  857.                 xdef    _PATCH_FreeVec
  858.  
  859. _PATCH_FreeVec  PUSH    a0-a3/a6/d0-d2
  860.  
  861.                 move.l  a1,d2           ; d2=Vec
  862.                 beq.b   .Exit
  863.  
  864.                 move.l  _PatchPool,d0
  865.                 beq.b   .Exit
  866.                 move.l  d0,a2           ; a2=PatchPool
  867.  
  868.                 move.l  _SysBase,a6
  869.  
  870.                 lea.l   _PatchPoolKey,a0
  871.                 move.l  a0,a3           ; a3=PatchPoolKey
  872.                 CALLOS  ObtainSemaphore
  873.  
  874.                 move.l  a2,a0
  875.                 move.l  d2,a1
  876.                 move.l  -(a1),d0
  877.                 CALLOS  FreePooled
  878.  
  879.                 move.l  a3,a0
  880.                 CALLOS  ReleaseSemaphore
  881.  
  882. .Exit           PULL    a0-a3/a6/d0-d2
  883.                 rts
  884.  
  885. ;***************************************************************************;
  886. ; _PATCH_LockNameToVec() ; Get the path of a lock in a vector ;
  887. ;
  888. ; void PATCH_LockNameToVec( register __d1 BPTR InLock );
  889.  
  890.                 xdef    _PATCH_LockNameToVec
  891.  
  892.                 xref    _DOSBase
  893.  
  894. _PATCH_LockNameToVec
  895.                 PUSH    d1-d3/d7/a0-a1/a6
  896.  
  897.                 move.l  d1,d2
  898.  
  899.                 move.l  _DOSBase,a6
  900.                 CALLOS  IoErr   ; Note: We *MUST* keep the existing IoErr
  901.                 move.l  d0,d7   ;       code intact!
  902.  
  903.                 move.l  d2,d1
  904.                 move.l  #256,d3         ; d3=Length
  905.                 move.l  d3,d0
  906.                 bsr     _PATCH_AllocVec
  907.                 move.l  d0,d2           ; d2=Buf
  908.                 beq.b   .Exit
  909.  
  910.                 CALLOS  NameFromLock    ; d1=Lock, d2=Buf, d3=BufLen
  911.                 tst.l   d0
  912.                 bne.b   .Exit
  913.  
  914.                 move.l  d2,a1
  915.                 lea.l   STR_DefaultName(pc),a0
  916. .StrCpyLp       move.b  (a0)+,(a1)+
  917.                 bne.b   .StrCpyLp
  918.  
  919. .Exit           move.l  d7,d1
  920.                 CALLOS  SetIoErr
  921.  
  922.                 move.l  d2,d0
  923.                 PULL    d1-d3/d7/a0-a1/a6
  924.                 tst.l   d0
  925.                 rts
  926.  
  927. ;***************************************************************************;
  928.  
  929. STR_UnnamedFont dc.b    "(unnamed font)",0
  930. STR_DefaultName dc.b    "(unable to get name)",0
  931. STR_DOSName     dc.b    "dos.library",0
  932.  
  933.                 cnop    0,4
  934.  
  935. ;***************************************************************************;
  936.  
  937.                 END
  938.  
  939.